#include "D3D9_PCH.h"
#include "PointSpriteComponent.h"

// Ref : http://www.telnet.or.kr/directx/graphics/programmingguide/advancedtopics/vertexpipe/geometry/pointsprites/pointsprites.htm

DWORD ToDWORD(float f) { return *((DWORD*)&f); }
const DWORD CPointSpriteComponent::PointSprite::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

CPointSpriteComponent::CPointSpriteComponent(void)
	: m_fSize( 30 )
	, m_pVB( NULL )
	, m_pTex( NULL )
{
	init();
}

CPointSpriteComponent::~CPointSpriteComponent(void)
{
	SAFE_RELEASE( m_pVB );
	SAFE_RELEASE( m_pTex );
}

void CPointSpriteComponent::init() {
	
	// create vertex buffer
	HRESULT hr;
	hr = g_pDevice->CreateVertexBuffer(
		1 * sizeof(PointSprite),
		D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY,
		PointSprite::FVF,
		D3DPOOL_DEFAULT, // D3DPOOL_MANAGED can't be used with D3DUSAGE_DYNAMIC 
		&m_pVB,
		0);

	assert( SUCCEEDED(hr) );
	
	// add point
	PointSprite* p;
	m_pVB->Lock( 0, sizeof(PointSprite), (void**)&p, D3DLOCK_DISCARD );
		p->position = D3DXVECTOR3(0,0,0);
		p->color = D3DXCOLOR(1,0,0,1);
	m_pVB->Unlock();

	D3DXCreateTextureFromFile( *g_pDevice, _T("./Resource/Arrow.png"), &m_pTex );
}

void CPointSpriteComponent::preRender() const {

	g_pDevice->SetRenderState(D3DRS_LIGHTING, false);
	g_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, true);
	g_pDevice->SetRenderState(D3DRS_POINTSIZE, ToDWORD(m_fSize));
		
	// use alpha from texture
/*	g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

	g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	g_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);*/
}

void CPointSpriteComponent::postRender() const {
	
	g_pDevice->SetRenderState(D3DRS_LIGHTING,          true);
	g_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, false);
	g_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE,  false);
	g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,  false);

}

void CPointSpriteComponent::Render() const {
	preRender();

	g_pDevice->SetStreamSource( 0, m_pVB, 0, sizeof(PointSprite) );
	g_pDevice->SetFVF( PointSprite::FVF );
	g_pDevice->SetTexture( 0, m_pTex );

	g_pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 1 );

	postRender();
}
